package com.vcredit.creditcat.service.product.h5;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.bird.enumtype.BankEnum;
import com.vcredit.creditcat.dto.product.h5.BindBankCardParamDto;
import com.vcredit.creditcat.dto.product.h5.CheckOrderResultDto;
import com.vcredit.creditcat.dto.product.h5.CreateOrderParamDto;
import com.vcredit.creditcat.dto.product.h5.LoanBindCardDto;
import com.vcredit.creditcat.dto.product.h5.LoanBindCardListDto;
import com.vcredit.creditcat.dto.product.h5.SdLoanBankCardInfoDto;
import com.vcredit.creditcat.dto.product.h5.SdOrderReviewInfoDto;
import com.vcredit.creditcat.dto.product.h5.SdTryCalculateParamDto;
import com.vcredit.creditcat.dto.product.h5.SdTryCalculateResultDto;
import com.vcredit.creditcat.dto.product.h5.TryCalculateParamDto;
import com.vcredit.creditcat.dto.product.h5.TryCalculateResultDto;
import com.vcredit.creditcat.enumtype.ProductAuditResultEnum;
import com.vcredit.creditcat.enumtype.product.sd.SDLoanOrderStatusEnum;
import com.vcredit.creditcat.manager.product.h5.AfterCreditAdaptor;
import com.vcredit.creditcat.model.AuthIdentity;
import com.vcredit.creditcat.model.BankInfo;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustCard;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.service.AuthIdentityService;
import com.vcredit.creditcat.service.BankInfoService;
import com.vcredit.creditcat.service.CustCardService;
import com.vcredit.creditcat.service.CustProductApplyService;
import com.vcredit.creditcat.service.product.sd.SDApplyServiceImpl;
import com.vcredit.creditcat.util.Utility;
import com.vcredit.creditcat.vo.product.h5.SdCheckFacePairResultDataVo;
import com.vcredit.creditcat.vo.product.h5.SdCheckOrderResultDataVo;
import com.vcredit.creditcat.vo.product.h5.SdCommonResultVo;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.exception.BaseException;
import com.vcredit.framework.util.HttpRequest;
import com.vcredit.framework.util.JacksonUtil;

@Service(AfterCreditAdaptor.BEANNAME_PREFIX + 3)
public class SdAfterCreditService implements IAfterCreditService {
	
	private static final Logger LOG = LoggerFactory.getLogger(SdAfterCreditService.class);
	
	@Autowired
	private AuthIdentityService authIdentityService;
	@Autowired
	private CustProductApplyService custProductApplyService;
	@Autowired
	private CustCardService custCardService;
	@Autowired
	private AfterCreditService afterCreditService;
	@Autowired
	private BankInfoService bankInfoService;
	
	
	@Value("${product.sd.checkOrder.url}")
	private String checkOrderUrl; 
	@Value("${product.sd.tryCalculate.url}")
	private String tryCalculateUrl;
	@Value("${product.sd.checkFacePair.url}")
	private String checkFacePairUrl;
	@Value("${product.sd.submitOrder.url}")
	private String submitOrderUrl;
	@Value("${product.sd.queryOrder.url}")
	private String queryOrderUrl;
	
	@Value("${resource.soft.url}")
	
	
	private String imagBaseUrl;

	/**
	 * 闪贷借款可交单
	 * @author zhaoqi01
	 * @param cust
	 * @return
	 * @throws Exception 
	 */
	@Log
	public CheckOrderResultDto checkUser(Long productId, Cust cust) throws Exception {
		CustProductApply custProductApply = custProductApplyService.findByCustAndProduct(cust.getCustId(),3L);
		String custId = SDApplyServiceImpl.CUST_PREFIX + cust.getCustId();
			
		
		Map<String,Object> checkOrderParam = new HashMap<String,Object>();
		checkOrderParam.put("custId", custId);		
		checkOrderParam.put("loanAmount", custProductApply.getCreditAmt());
		
		
		String checkOrderParamJson = JacksonUtil.Obj2Json(checkOrderParam);
		
		LOG.info("------------闪贷可交单入参：" + checkOrderParamJson+"#"+checkOrderUrl);
		
		String resultJson = HttpRequest.doJson(checkOrderUrl, checkOrderParamJson);
		
		LOG.info("------------闪贷可交单出参：" + resultJson);
		
		SdCommonResultVo<SdCheckOrderResultDataVo> sdCommonResultVo = JacksonUtil.Json2Obj(resultJson, new TypeReference<SdCommonResultVo<SdCheckOrderResultDataVo>>(){});
		
		if(sdCommonResultVo.isSuccess()) {
			return new CheckOrderResultDto(sdCommonResultVo.getData().getCanLoanFlag(), 
					sdCommonResultVo.getData().getPrecheckFailTips());
		} else {
			throw new BaseException(sdCommonResultVo.getMessage());
		}
	}

	/**
	 * 试算，根据金额计算可选期数、费用
	 * @author zhaoqi01
	 * @param loanAmount
	 * @param cust
	 * @return
	 * @throws Exception 
	 */
	@Log
	public SdTryCalculateResultDto sdTryCalculate(SdTryCalculateParamDto param, Cust cust) throws Exception {
		String custId = SDApplyServiceImpl.CUST_PREFIX + cust.getCustId();
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("custId", custId);
		paramMap.put("loanAmount", param.getAmount());
		String paramJson = JacksonUtil.Obj2Json(paramMap);
		
		LOG.info("------------闪贷试算入参："+tryCalculateUrl+"#" + paramJson);
		
		String resultJson = HttpRequest.doJson(tryCalculateUrl, paramJson);
		
		LOG.info("------------闪贷试算出参：" + resultJson);
		
		SdCommonResultVo<SdTryCalculateResultDto> sdCommonResultVo = JacksonUtil.Json2Obj(resultJson, new TypeReference<SdCommonResultVo<SdTryCalculateResultDto>>(){});
	
		if(sdCommonResultVo.isSuccess()) {
			return sdCommonResultVo.getData();
		} else {
			throw new BaseException(sdCommonResultVo.getMessage());
		}
	}

	/**
	 * 提交订单
	 * @author zhaoqi01
	 * @param param
	 * @param cust
	 * @return
	 * @throws Exception
	 */
	@Log
	public String submitLoan(Long productId, CreateOrderParamDto param, Cust cust) throws Exception{
		// 上传身份证照片：正片、面部
		Boolean checkFacePairResult = this.checkFacePair(cust);
		if(!checkFacePairResult) {
			return null;
		}
		
		// 提交订单
		String orderId = this.submitOrder(param,cust.getCustId());
		return orderId;
	}
	
	/**
	 * 提交订单
	 * @author zhaoqi01
	 * @param param
	 * @param custId
	 * @return
	 * @throws Exception 
	 */
	private String submitOrder(CreateOrderParamDto param, Long custId) throws Exception {
		// 校验银行卡是否正确
		CustCard custCard = new CustCard();
		custCard.setCustId(custId);
		custCard.setAccountNo(param.getBankCardId());
		custCard.setCardType(1);
		List<CustCard> custCardList = custCardService.find(custCard);
		if(Utility.isNullOrEmpty(custCardList)) {
			return null;
		}
		
		// 签名图片
		CustProductApply custProductApply = custProductApplyService.findByCustAndProduct(custId, 3L);
		String signatureUrl = imagBaseUrl + "/" + custProductApply.getSignature();
		LOG.info("------------ 闪贷提交订单入参 签名图片地址：" + signatureUrl);
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("custId", SDApplyServiceImpl.CUST_PREFIX + custId);
		paramMap.put("loanAmount",(Float.valueOf(param.getLoanAmount())).intValue());
		paramMap.put("loanPeriod", param.getLoanPeriod());
		paramMap.put("bankCardId", param.getBankCardId());
		paramMap.put("bankCode", param.getBankCode());
		//测试代码
		//paramMap.put("bankCardId","6227002586510129199");
		//paramMap.put("bankCode", "CCB");
		paramMap.put("signature", Utility.imgBase64Str(signatureUrl));
		
		
		String paramJson = JacksonUtil.Obj2Json(paramMap);
		LOG.info("------------ 闪贷提交订单入参：" + paramJson);
		String submitResultJson = HttpRequest.doJson(submitOrderUrl, paramJson);
		LOG.info("------------ 闪贷提交订单出参：" + submitResultJson);
		
		SdCommonResultVo<Map<String, Long>> submitResult = JacksonUtil.Json2Obj(submitResultJson, new TypeReference<SdCommonResultVo<Map<String,Long>>>(){});
		
		if(submitResult.isSuccess() && submitResult.getData().get("orderId") != null) {
			String orderIdStr = submitResult.getData().get("orderId") + "";
			custProductApply.setOrderId(orderIdStr);
			custProductApply.setAuditResult(ProductAuditResultEnum.LoanApplying.getCode()); // 订单提交成功设置订单审核中状态
			custProductApplyService.update(custProductApply);
			return orderIdStr;
		}
		return null;
	}

	/**
	 * 上传身份证照片
	 * @author zhaoqi01
	 * @param cust
	 * @return
	 * @throws Exception
	 */
	private Boolean checkFacePair(Cust cust) throws Exception {
		String custId = SDApplyServiceImpl.CUST_PREFIX + cust.getCustId();
		AuthIdentity authIdentity = authIdentityService.findByProcessId(cust.getLastProccessId());
		String idFontUrl = imagBaseUrl + "/" + authIdentity.getIdFront();
		String idFaceUrl = imagBaseUrl + "/" + authIdentity.getIdFace();
		
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("custId", custId);
		String idImgData=Utility.imgBase64Str(idFontUrl);
		paramMap.put("idImgData", idImgData);
		String verifyImgData=Utility.imgBase64Str(idFaceUrl);
		paramMap.put("verifyImgData", verifyImgData);		
		paramMap.put("custHoldaddr", authIdentity.getAddress());
		
		String checkFacePairParamJson = JacksonUtil.Obj2Json(paramMap);
		checkFacePairParamJson=checkFacePairParamJson.replace("\\r\\n", "");
		LOG.info("------------闪贷人脸识别上传入参：\r\n"
		        +"------------idFontUrl:"+idFontUrl
		        +"------------idFaceUrl:"+idFaceUrl
		        +"#" + checkFacePairParamJson);
		String checkFacePairResultJson = HttpRequest.doJson(checkFacePairUrl, checkFacePairParamJson);
		LOG.info("------------闪贷人脸识别上传出参：" + checkFacePairParamJson);
		
		SdCommonResultVo<SdCheckFacePairResultDataVo> checkFacePairResult = JacksonUtil.Json2Obj(checkFacePairResultJson, new TypeReference<SdCommonResultVo<SdCheckFacePairResultDataVo>>(){});
		if(checkFacePairResult.isSuccess() && checkFacePairResult.getData().getPassAuth()) {
			return true;
		}
		return false;
	}

	/**
	 * 查询订单审核信息
	 * @author zhaoqi01
	 * @param cust
	 * @return
	 */
	public SdOrderReviewInfoDto queryReviewInfo(Cust cust) throws Exception {
		
		CustProductApply custProductApply = custProductApplyService.findByCustAndProduct(cust.getCustId(), 3L);
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("custId", SDApplyServiceImpl.CUST_PREFIX + cust.getCustId());
		paramMap.put("orderId", custProductApply.getOrderId());
		String paramJson = JacksonUtil.Obj2Json(paramMap);
		LOG.info("------------闪贷查询订单入参：" + paramJson);
		String queryOrderResultJson = HttpRequest.doJson(queryOrderUrl, paramJson);
		LOG.info("------------闪贷查询订单出参：" + queryOrderResultJson);
		

		SdCommonResultVo<SdOrderReviewInfoDto> queryOrderResult = JacksonUtil.Json2Obj(queryOrderResultJson, new TypeReference<SdCommonResultVo<SdOrderReviewInfoDto>>(){});
		if(!queryOrderResult.isSuccess()) {
			throw new BaseException("闪贷查询订单失败");
		}
		
		SdOrderReviewInfoDto dto=queryOrderResult.getData();	
		SdLoanBankCardInfoDto info=dto.getLoanBankCardInfo();
		String bannkCode=info.getBankCode();		
	    BankInfo bankInfo = bankInfoService.findAllForMap().get(bannkCode);
	    dto.setBankIcon(bankInfo.getBankIcon());
		
	    Integer auditResult = SDLoanOrderStatusEnum.getAuditResultByOrderStatus(dto.getOrderStatusCode());
	    if(null == auditResult) {
	    	throw new BaseException("闪贷提现订单状态错误");
	    }
	    // 更新审核状态 
	    custProductApply.setAuditResult(auditResult);
	    custProductApplyService.update(custProductApply);
	    
		return dto;
	}

	@Override
	public void bindCard(Long productId, BindBankCardParamDto param, Cust cust)
			throws Exception {
		afterCreditService.bindCustCard(param, cust);
	}

	@Override
	public TryCalculateResultDto tryCalculate(Long productId,
			TryCalculateParamDto param, Cust cust) throws Exception {
		return null;
	}

	/**
	 * 查询借记卡列表
	 * @author zhaoqi01
	 * @param cust
	 * @return
	 */
	@Log
	public LoanBindCardListDto loanbindCardList(Cust cust) {
		List<CustCard> list = custCardService.findByCustAndTypeOrderUpdate(cust.getCustId(), 1);
		List<LoanBindCardDto> LoanBindCardList = new ArrayList<LoanBindCardDto>();
		if(Utility.isNullOrEmpty(list)) {
			return new LoanBindCardListDto(LoanBindCardList);
		}
		Map<String, BankInfo> allBankInfo = bankInfoService.findAllForMap();
		for (int i = 0; i < list.size(); i++) {
			LoanBindCardDto loanBindCardDto = new LoanBindCardDto();
			if(i == 0) {
				loanBindCardDto.setIsDefault(true);
			}
			loanBindCardDto.setBankCard(list.get(i).getAccountNo());
			loanBindCardDto.setBankCode(list.get(i).getBankCode());
			loanBindCardDto.setBankName(BankEnum.getDescByCode(loanBindCardDto.getBankCode()));
			loanBindCardDto.setBankIcon(allBankInfo.get(loanBindCardDto.getBankCode()).getBankIcon());
			LoanBindCardList.add(loanBindCardDto);
		}
		return new LoanBindCardListDto(LoanBindCardList);
	}

}
